from datetime import datetime, timedelta, time
from typing import Annotated,Literal
from uuid import UUID

import uvicorn
from fastapi import FastAPI, Path, Query, Body,Cookie,Header
from fastapi.openapi.docs import get_swagger_ui_html, get_swagger_ui_oauth2_redirect_html, get_redoc_html
from starlette.staticfiles import StaticFiles
from pydantic import BaseModel, Field, HttpUrl, EmailStr

# 创建FastAPI实例，禁用掉FastAPI会自动生成Swagger UI和Redoc文档
app = FastAPI(docs_url=None, redoc_url=None)

# 静态文件挂载（路由与静态文件映射）
app.mount("/static", StaticFiles(directory="../statics"), name="static")


# 重新提供一个Swagger UI，相当于我们自己重写了这么一个路由
@app.get("/docs", include_in_schema=False)
def custom_swagger_ui():
    return get_swagger_ui_html(
        openapi_url = "/openapi.json",
        title = "Swagger UI for FastAPI",
        swagger_js_url="/static/swagger-ui-bundle.min.js",
        swagger_css_url="/static/swagger-ui.min.css"
    )
@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
    return get_swagger_ui_oauth2_redirect_html()

# 这里与Swagger UI一样，重新提供Redoc
@app.get("/redoc", include_in_schema=False)
def custom_redoc():
    return get_redoc_html(
        openapi_url = "/openapi.json",
        title = "Redoc for FastAPI",
        redoc_js_url="/static/redoc.standalone.js"
    )

class Item(BaseModel):
    name: str
    description: str | None = None
    price: float = 10.5
    tax: float | None = None
    tags: list[str] = []


@app.post("/items", response_model=Item)
async def create_item(item: Item):
    return item

@app.get("/items", response_model=list[Item])
async def read_items():
    return [
        {"name": "手机", "price": 2999.0},
        {"name": "电脑", "price": 6999.0, "tax": 20.5},
        {"name": "手表", "price": 1999, "tax": 8}
    ]

class UserIn(BaseModel):
    username: str
    password: str
    email: EmailStr
    full_name: str | None = None

# 响应的模型去掉了密码字
class UserOut(BaseModel):
    username: str
    email: EmailStr
    full_name: str | None = None

@app.post("/user",response_model=UserOut)
async def create_user(user: UserIn):
    return user

items = {
    "华为手机": {"name": "华为手机", "price": 3999.0},
    "小米手机": {"name": "小米手机", "description": "红米手机","price": 2999.0,"tags":[]},
    "苹果手机": {"name": "苹果手机", "description": None, "price": 4999.0,"tax": 10.5, "tags":["smartphone"]}
}

@app.get("/items/{item_name}",response_model=list[Item],response_model_exclude_unset=True)
async def read_item(item_name: str):
    result = [item for name, item in items.items() if item_name in name]
    return result


@app.get("/items2/{item_name}",response_model=list[Item],response_model_exclude_defaults=True)
async def read_item2(item_name: str):
    result = [item for name, item in items.items() if item_name in name]
    return result

@app.get("/items3/{item_name}",response_model=list[Item],response_model_exclude_none=True)
async def read_item3(item_name: str):
    result = [item for name, item in items.items() if item_name in name]
    return result

@app.get("/items4/{item_name}",response_model=Item,response_model_include={"name","price"})
async def read_item4(item_name: str):
    result = [item for name, item in items.items() if item_name in name]
    return result[0]

@app.get("/items5/{item_name}",response_model=Item,response_model_exclude=("name","price"))
async def read_item5(item_name: str):
    result = [item for name, item in items.items() if item_name in name]
    return result[0]


if __name__ == '__main__':
    app.debug = True
    uvicorn.run("main:app", host="127.0.0.1", port=8016, reload=True)

